package org.jeecg.modules.oms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.oms.entity.SemiProductSalesOrder;
import org.jeecg.modules.oms.dto.SemiProductSalesOrderWithTransactionsDTO;
import org.jeecg.modules.oms.entity.SemiProductSalesOrderTransaction;
import org.jeecg.modules.oms.mapper.SemiProductSalesOrderMapper;
import org.jeecg.modules.oms.service.ISemiProductSalesOrderDetailService;
import org.jeecg.modules.oms.service.ISemiProductSalesOrderProgressService;
import org.jeecg.modules.oms.service.ISemiProductSalesOrderService;
import org.jeecg.modules.oms.service.ISemiProductSalesOrderTransactionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.apache.shiro.SecurityUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * 半成品销售订单Service实现类
 */
@Service
@Slf4j
public class SemiProductSalesOrderServiceImpl extends ServiceImpl<SemiProductSalesOrderMapper, SemiProductSalesOrder> implements ISemiProductSalesOrderService {

    @Autowired
    private SemiProductSalesOrderMapper semiProductSalesOrderMapper;
    
    @Autowired
    private ISemiProductSalesOrderDetailService detailService;
    
    @Autowired
    private ISemiProductSalesOrderProgressService progressService;
    
    @Autowired
    private ISemiProductSalesOrderTransactionService transactionService;

    @Override
    public IPage<SemiProductSalesOrder> queryOrderPage(Page<SemiProductSalesOrder> page, SemiProductSalesOrder order) {
        try {
            return semiProductSalesOrderMapper.selectOrderPageWithDetail(page, order);
        } catch (Exception e) {
            log.error("分页查询半成品销售订单失败", e);
            throw new JeecgBootException("查询订单失败: " + e.getMessage());
        }
    }

    @Override
    public SemiProductSalesOrder getByOrderNo(String orderNo, Integer tenantId) {
        if (oConvertUtils.isEmpty(orderNo)) {
            return null;
        }
        try {
            return semiProductSalesOrderMapper.selectByOrderNo(orderNo, tenantId);
        } catch (Exception e) {
            log.error("根据订单号查询订单失败: orderNo={}, tenantId={}", orderNo, tenantId, e);
            throw new JeecgBootException("查询订单失败: " + e.getMessage());
        }
    }

    @Override
    public List<SemiProductSalesOrder> getByCustomerId(String customerId) {
        if (oConvertUtils.isEmpty(customerId)) {
            return null;
        }
        try {
            return semiProductSalesOrderMapper.selectByCustomerId(customerId);
        } catch (Exception e) {
            log.error("根据客户ID查询订单失败: customerId={}", customerId, e);
            throw new JeecgBootException("查询订单失败: " + e.getMessage());
        }
    }

    @Override
    public List<SemiProductSalesOrder> getByProjectId(String projectId) {
        if (oConvertUtils.isEmpty(projectId)) {
            return null;
        }
        try {
            return semiProductSalesOrderMapper.selectByProjectId(projectId);
        } catch (Exception e) {
            log.error("根据项目ID查询订单失败: projectId={}", projectId, e);
            throw new JeecgBootException("查询订单失败: " + e.getMessage());
        }
    }

    @Override
    public List<SemiProductSalesOrder> getByStatus(Integer status) {
        if (status == null) {
            return null;
        }
        try {
            return semiProductSalesOrderMapper.selectByStatus(status);
        } catch (Exception e) {
            log.error("根据状态查询订单失败: status={}", status, e);
            throw new JeecgBootException("查询订单失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addSemiProductSalesOrder(SemiProductSalesOrder order) {
        try {
            // 获取当前用户信息
            LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

            // 生成订单编号
            if (oConvertUtils.isEmpty(order.getOrderNo())) {
                order.setOrderNo(generateOrderNo(order.getTenantId()));
            }

            // 检查订单号是否重复
            if (checkOrderNoExists(order.getOrderNo(), order.getTenantId(), null)) {
                throw new JeecgBootException("订单编号已存在: " + order.getOrderNo());
            }

            // 设置默认值
            if (order.getStatus() == null) {
                order.setStatus(0); // 默认待审核
            }
            if (order.getPayStatus() == null) {
                order.setPayStatus(0); // 默认未付清
            }
            if (order.getTotalAmount() == null) {
                order.setTotalAmount(BigDecimal.ZERO);
            }
            if (order.getPaidAmount() == null) {
                order.setPaidAmount(BigDecimal.ZERO);
            }
            if (order.getUnpaidAmount() == null) {
                order.setUnpaidAmount(order.getTotalAmount());
            }

            order.setCreateTime(new Date());
            order.setDelFlag(0);

            // 保存订单
            boolean result = this.save(order);
            if (!result) {
                throw new JeecgBootException("保存订单失败");
            }

            // 记录进度
            progressService.recordStatusChange(order.getId(), null, order.getStatus(), 
                order.getCreateBy(), order.getCreateBy(), "创建订单", "创建半成品销售订单", "订单创建", null);

            log.info("添加半成品销售订单成功: orderNo={}", order.getOrderNo());
            return true;
        } catch (Exception e) {
            log.error("添加半成品销售订单失败", e);
            throw new JeecgBootException("添加订单失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addSemiProductSalesOrderWithTransactions(SemiProductSalesOrder order, List<SemiProductSalesOrderTransaction> transactionList) {
        try {
            // 先保存订单
            boolean orderResult = addSemiProductSalesOrder(order);
            if (!orderResult) {
                throw new JeecgBootException("保存订单失败");
            }

            // 保存订单明细
            if (order instanceof SemiProductSalesOrderWithTransactionsDTO) {
                SemiProductSalesOrderWithTransactionsDTO orderDTO = (SemiProductSalesOrderWithTransactionsDTO) order;
                if (orderDTO.getDetailList() != null && !orderDTO.getDetailList().isEmpty()) {
                    detailService.saveOrderDetailBatch(order.getId(), orderDTO.getDetailList());
                }
            }

            // 保存交易记录
            if (transactionList != null && !transactionList.isEmpty()) {
                for (SemiProductSalesOrderTransaction transaction : transactionList) {
                    transaction.setOrderId(order.getId());
                    transaction.setCreateTime(new Date());
                    transaction.setTenantId(order.getTenantId());
                    
                    // 获取当前用户信息
                    LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
                    if (loginUser != null) {
                        transaction.setCreateBy(loginUser.getUsername());
                    }
                    
                    transactionService.addTransaction(transaction);
                }

                // 重新计算订单金额
                updateOrderAmountByTransactions(order.getId());
            }

            log.info("添加半成品销售订单及交易记录成功: orderNo={}", order.getOrderNo());
            return true;
        } catch (Exception e) {
            log.error("添加半成品销售订单及交易记录失败", e);
            throw new JeecgBootException("添加订单失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateSemiProductSalesOrder(SemiProductSalesOrder order) {
        try {
            // 获取当前用户信息
            LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            if (loginUser != null) {
                order.setUpdateBy(loginUser.getUsername());
            }

            // 检查订单号是否重复
            if (oConvertUtils.isNotEmpty(order.getOrderNo()) && 
                checkOrderNoExists(order.getOrderNo(), order.getTenantId(), order.getId())) {
                throw new JeecgBootException("订单编号已存在: " + order.getOrderNo());
            }

            order.setUpdateTime(new Date());

            // 更新订单
            boolean result = this.updateById(order);
            if (!result) {
                throw new JeecgBootException("更新订单失败");
            }

            log.info("更新半成品销售订单成功: id={}", order.getId());
            return true;
        } catch (Exception e) {
            log.error("更新半成品销售订单失败", e);
            throw new JeecgBootException("更新订单失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateSemiProductSalesOrderWithTransactions(SemiProductSalesOrder order, List<SemiProductSalesOrderTransaction> transactionList) {
        try {
            // 先更新订单
            boolean orderResult = updateSemiProductSalesOrder(order);
            if (!orderResult) {
                throw new JeecgBootException("更新订单失败");
            }

            // 处理订单明细
            if (order instanceof SemiProductSalesOrderWithTransactionsDTO) {
                SemiProductSalesOrderWithTransactionsDTO orderDTO = (SemiProductSalesOrderWithTransactionsDTO) order;
                if (orderDTO.getDetailList() != null && !orderDTO.getDetailList().isEmpty()) {
                    // 删除现有明细，重新保存
                    detailService.deleteByOrderId(order.getId());
                    detailService.saveOrderDetailBatch(order.getId(), orderDTO.getDetailList());
                }
            }

            // 处理交易记录
            if (transactionList != null) {
                // 获取现有交易记录
                List<SemiProductSalesOrderTransaction> existingTransactions = transactionService.getByOrderId(order.getId());
                
                // 获取当前用户信息
                LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
                String currentUser = loginUser != null ? loginUser.getUsername() : null;

                // 处理新增和更新的交易记录
                for (SemiProductSalesOrderTransaction transaction : transactionList) {
                    transaction.setOrderId(order.getId());
                    transaction.setTenantId(order.getTenantId());
                    
                    if (oConvertUtils.isEmpty(transaction.getId())) {
                        // 新增交易记录
                        transaction.setCreateTime(new Date());
                        transaction.setCreateBy(currentUser);
                        transactionService.addTransaction(transaction);
                    } else {
                        // 更新交易记录
                        transaction.setUpdateTime(new Date());
                        transaction.setUpdateBy(currentUser);
                        transactionService.updateTransaction(transaction);
                    }
                }

                // 重新计算订单金额
                updateOrderAmountByTransactions(order.getId());
            }

            log.info("更新半成品销售订单及交易记录成功: id={}", order.getId());
            return true;
        } catch (Exception e) {
            log.error("更新半成品销售订单及交易记录失败", e);
            throw new JeecgBootException("更新订单失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteSemiProductSalesOrder(String id) {
        try {
            if (oConvertUtils.isEmpty(id)) {
                throw new JeecgBootException("订单ID不能为空");
            }

            // 获取当前用户信息
            LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            String updateBy = loginUser != null ? loginUser.getUsername() : "system";

            // 1. 删除订单明细
            try {
                detailService.deleteByOrderId(id);
                log.info("删除订单明细成功: orderId={}", id);
            } catch (Exception e) {
                log.error("删除订单明细失败: orderId={}", id, e);
                throw new JeecgBootException("删除订单明细失败: " + e.getMessage());
            }

            // 2. 删除交易记录
            try {
                transactionService.deleteByOrderId(id);
                log.info("删除交易记录成功: orderId={}", id);
            } catch (Exception e) {
                log.error("删除交易记录失败: orderId={}", id, e);
                throw new JeecgBootException("删除交易记录失败: " + e.getMessage());
            }

            //删除订单进度表
            try {
                progressService.deleteByOrderId(id);
                log.info("删除订单进度表成功: orderId={}", id);
            } catch (Exception e) {
                log.error("删除订单进度表失败: orderId={}", id, e);
                throw new JeecgBootException("删除订单进度表失败: " + e.getMessage());
            }

            // 3. 删除订单主表
            boolean result = this.removeById(id);
            if (!result) {
                throw new JeecgBootException("删除订单失败");
            }

            log.info("删除半成品销售订单成功: id={}", id);
            return true;
        } catch (Exception e) {
            log.error("删除半成品销售订单失败", e);
            throw new JeecgBootException("删除订单失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean auditOrder(String id, Integer status, String auditBy, String auditRemark) {
        try {
            if (oConvertUtils.isEmpty(id) || status == null) {
                throw new JeecgBootException("参数不能为空");
            }

            // 获取原订单信息
            SemiProductSalesOrder oldOrder = this.getById(id);
            if (oldOrder == null) {
                throw new JeecgBootException("订单不存在");
            }

            // 更新订单状态
            boolean result = updateOrderStatus(id, status, auditBy);
            if (!result) {
                throw new JeecgBootException("更新订单状态失败");
            }

            // 记录审核进度
            String operationType = status == 1 ? "审核通过" : "审核驳回";
            progressService.recordStatusChange(id, oldOrder.getStatus(), status, 
                auditBy, auditBy, operationType, "订单审核", auditRemark, auditRemark);

            log.info("审核半成品销售订单成功: id={}, status={}", id, status);
            return true;
        } catch (Exception e) {
            log.error("审核半成品销售订单失败", e);
            throw new JeecgBootException("审核订单失败: " + e.getMessage());
        }
    }

    @Override
    public boolean updateOrderStatus(String id, Integer status, String updateBy) {
        try {
            if (oConvertUtils.isEmpty(id) || status == null) {
                return false;
            }

            int result = semiProductSalesOrderMapper.updateStatus(id, status, updateBy);
            return result > 0;
        } catch (Exception e) {
            log.error("更新订单状态失败: id={}, status={}", id, status, e);
            throw new JeecgBootException("更新订单状态失败: " + e.getMessage());
        }
    }

    @Override
    public boolean updateOrderAmount(String id, BigDecimal totalAmount, BigDecimal paidAmount, 
                                   BigDecimal unpaidAmount, Integer payStatus, String updateBy) {
        try {
            if (oConvertUtils.isEmpty(id)) {
                return false;
            }

            int result = semiProductSalesOrderMapper.updateAmount(id, totalAmount, paidAmount, 
                unpaidAmount, payStatus, updateBy);
            return result > 0;
        } catch (Exception e) {
            log.error("更新订单金额失败: id={}", id, e);
            throw new JeecgBootException("更新订单金额失败: " + e.getMessage());
        }
    }

    @Override
    public String generateOrderNo(Integer tenantId) {
        try {
            // 生成格式: SP + 租户ID(2位) + 年月日(8位) + 序号(4位)
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            String dateStr = sdf.format(new Date());
            String tenantStr = String.format("%02d", tenantId != null ? tenantId : 0);
            
            // 查询当天已有订单数量
            String prefix = "BCP" + tenantStr + dateStr;
            QueryWrapper<SemiProductSalesOrder> queryWrapper = new QueryWrapper<>();
            queryWrapper.likeRight("order_no", prefix);
            queryWrapper.eq("del_flag", 0);
            long countLong = this.count(queryWrapper);
            int count = (int) countLong;
            
            String sequence = String.format("%04d", count + 1);
            return prefix + sequence;
        } catch (Exception e) {
            log.error("生成订单编号失败", e);
            throw new JeecgBootException("生成订单编号失败: " + e.getMessage());
        }
    }

    @Override
    public boolean checkOrderNoExists(String orderNo, Integer tenantId, String excludeId) {
        try {
            if (oConvertUtils.isEmpty(orderNo)) {
                return false;
            }

            QueryWrapper<SemiProductSalesOrder> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("order_no", orderNo);
            queryWrapper.eq("tenant_id", tenantId);
            queryWrapper.eq("del_flag", 0);
            
            if (oConvertUtils.isNotEmpty(excludeId)) {
                queryWrapper.ne("id", excludeId);
            }

            return this.count(queryWrapper) > 0;
        } catch (Exception e) {
            log.error("检查订单号是否存在失败: orderNo={}", orderNo, e);
            return false;
        }
    }

    @Override
    public Integer countOrders(SemiProductSalesOrder order) {
        try {
            return semiProductSalesOrderMapper.countOrders(order);
        } catch (Exception e) {
            log.error("统计订单数量失败", e);
            throw new JeecgBootException("统计订单数量失败: " + e.getMessage());
        }
    }

    @Override
    public BigDecimal calculateOrderProfit(String id) {
        try {
            if (oConvertUtils.isEmpty(id)) {
                return BigDecimal.ZERO;
            }

            // 计算总金额和总成本
            BigDecimal totalAmount = detailService.calculateTotalAmount(id);
            BigDecimal totalCost = detailService.calculateTotalCost(id);
            
            if (totalAmount == null) totalAmount = BigDecimal.ZERO;
            if (totalCost == null) totalCost = BigDecimal.ZERO;
            
            return totalAmount.subtract(totalCost);
        } catch (Exception e) {
            log.error("计算订单利润失败: id={}", id, e);
            throw new JeecgBootException("计算订单利润失败: " + e.getMessage());
        }
    }

    /**
     * 根据交易记录重新计算订单金额
     * @param orderId 订单ID
     */
    private void updateOrderAmountByTransactions(String orderId) {
        try {
            // 计算已付金额
            BigDecimal paidAmount = transactionService.calculatePaidAmount(orderId);
            
            // 获取订单信息
            SemiProductSalesOrder order = this.getById(orderId);
            if (order == null) {
                return;
            }
            
            // 计算未付金额
            BigDecimal totalAmount = order.getTotalAmount() != null ? order.getTotalAmount() : BigDecimal.ZERO;
            BigDecimal unpaidAmount = totalAmount.subtract(paidAmount);
            
            // 确保未付金额不为负数
            if (unpaidAmount.compareTo(BigDecimal.ZERO) < 0) {
                unpaidAmount = BigDecimal.ZERO;
            }
            
            // 更新订单金额信息
            order.setPaidAmount(paidAmount);
            order.setUnpaidAmount(unpaidAmount);
            
            // 更新付款状态
            Integer payStatus = 0; // 默认未付清
            if (paidAmount.compareTo(BigDecimal.ZERO) > 0) {
                if (unpaidAmount.compareTo(BigDecimal.ZERO) == 0) {
                    payStatus = 2; // 已付清
                } else {
                    payStatus = 1; // 部分付款
                }
            }
            order.setPayStatus(payStatus);
            
            // 更新订单
            this.updateById(order);
            
            log.info("更新订单金额成功: orderId={}, paidAmount={}, unpaidAmount={}, payStatus={}", 
                    orderId, paidAmount, unpaidAmount, payStatus);
        } catch (Exception e) {
            log.error("更新订单金额失败: orderId={}", orderId, e);
        }
    }
}
